#include <iostream>
#include <set>
#include <cmath>
using std::cout;
using std::endl;
using std::set;

class Point{
public:
    int _x;
    int _y;
public:
    Point(int x = 0, int y = 0);
    //    ~Point();

    double get_distance() const;
};

Point::Point(int x, int y)
    :_x(x)
     ,_y(y){
     }

double Point::get_distance() const{
    return hypot(_x, _y);
}

namespace std{

#if 0
template <>
    struct less<Point>{
        bool operator()(const Point &pt1, const Point& pt2) const{
            cout << "template <> struct std::less" << endl;
            //            if(pt1.get_distance() < pt2.get_distance()){
            //                return true;
            //            }
            //            else if(pt1._x < pt2._x){
            //                return true;
            //            }
            //            else{
            //                return false;
            //            }
            if(pt1.get_distance() != pt2.get_distance()){
                return pt1.get_distance() < pt2.get_distance();
            }
            else if(pt1._x != pt2._x){
                return pt1._x < pt2._x;
            }
            else{
                return pt1._y < pt2._y;
            }
        }
    };
#endif

#if 0
bool operator<(const Point &pt1, const Point& pt2) {
    cout << "operator<(const Point &pt1, const Point& pt2)" << endl;
    if(pt1.get_distance() != pt2.get_distance()){
        return pt1.get_distance() < pt2.get_distance();
    }
    else if(pt1._x != pt2._x){
        return pt1._x < pt2._x;
    }
    else{
        return pt1._y < pt2._y;
    }
}
#endif

    struct Compare_Point{
        bool operator()(const Point &pt1, const Point& pt2) const{
            cout << "operator()(const Point &pt1, const Point& pt2) const{" << endl;
            if(pt1.get_distance() != pt2.get_distance()){
                return pt1.get_distance() < pt2.get_distance();
            }
            else if(pt1._x != pt2._x){
                return pt1._x < pt2._x;
            }
            else{
                return pt1._y < pt2._y;
            }
        }
    };
}

void test(){
    //set<Point> s = {Point(1, 6), Point(4, 1), Point(-1, 1), Point(1, 8), Point(1, 8), Point(1, 1)};
    set<Point, std::Compare_Point> s = {Point(1, 6), Point(4, 1), Point(-1, 1), Point(1, 8), Point(1, 8), Point(1, 1)};
    for(auto& pt : s){
        cout << "(" << pt._x << " " << pt._y << ")" << "    ";
    }
    cout << endl;
}

int main()
{
    test();
    return 0;
}

